#include "Characters.h"

#include "CocosHelper.h"
#include "GameDefine.h"


using namespace cocos2d;

CZhaoYun::CZhaoYun()
	: m_pBatchNode(NULL)
	, m_pCurSprite(NULL)
	, m_state(STATE_NONE)
	, m_bCanAttack(true)
	, m_batterTimer(0)
	, m_bWaitBatter(false)
{

}

void CZhaoYun::InitState(cocos2d::CCNode *pParent)
{
	m_pBatchNode = CCSpriteBatchNode::batchNodeWithFile("chars/zhaoyun.png");
	pParent->addChild(m_pBatchNode);

	m_pCurSprite = CCSprite::spriteWithSpriteFrameName("zhaoyun_run_left_1.png");
	m_pBatchNode->addChild(m_pCurSprite);

	m_ptPos = ccp(GAME_WIDTH/2, GAME_HEIGHT/2);
	m_pCurSprite->setPosition(m_ptPos);

	m_pCurSprite->setScale(0.75f);

	m_walkDir = DIRECTION_RIGHT;
	m_attackDir = DIRECTION_RIGHT;

	Walk(RIGHT);

}

void CZhaoYun::Remove()
{
	if(NULL != m_pCurSprite)
	{
		m_pCurSprite = NULL;
		m_pCurSprite->removeFromParentAndCleanup(true);
	}

	if(NULL != m_pBatchNode)
	{
		m_pBatchNode = NULL;
		m_pBatchNode->removeFromParentAndCleanup(true);
	}
}

void CZhaoYun::Attack()
{

	if(!m_bCanAttack)
	{
		return;
	}

	m_batterTimer = 0;

	if(m_bWaitBatter)
	{
		m_bCanAttack = false;
		m_bWaitBatter = false;
		AttackNormal2(m_attackDir);
	}
	else if(rand() % 100 < 10)
	{
		
		AttackCirtical(m_attackDir);
		m_bCanAttack = false;
	}
	else if(rand() % 100 < 10)
	{
		Skill1(m_attackDir);
		m_bCanAttack = false;
		
	}
	else
	{
		m_bCanAttack = false;
		m_batterTimer = 1.0f;
		m_bWaitBatter = true;
		AttackNormal1(m_attackDir);
	}
}

void CZhaoYun::OnAttack()
{
	
	m_bCanAttack = true;

	if(!m_bWaitBatter)
	{
		Walk(m_walkDir);
	}
	

}

void CZhaoYun::AttackNormal1(int dir)
{

	m_pCurSprite->stopAllActions();
	CAnimationHelper::AnimateWithCall(this, callfunc_selector(CZhaoYun::OnAttack), 
		m_pCurSprite, 1, 6, "zhaoyun_attack_normal1_%d.png", ZHAOYUN_ATTACK_DELAY);

	if(dir == DIRECTION_RIGHT)
	{
		m_pCurSprite->setAnchorPoint(ccp(81/171.0f, 67.0f/117));
		m_pCurSprite->setFlipX(false);
		m_pCurSprite->setFlipY(false);
	}
	else
	{
		m_pCurSprite->setAnchorPoint(ccp(90/171.0f, 67.0f/117));
		m_pCurSprite->setFlipX(true);
		m_pCurSprite->setFlipY(false);
	}
	
	m_state = STATE_ATTACK_NORMAL1;
}

void CZhaoYun::AttackNormal2(int dir)
{
	CAnimationHelper::AnimateWithCall(this, callfunc_selector(CZhaoYun::OnAttack), 
		m_pCurSprite, 1, 6, "zhaoyun_attack_normal2_%d.png", ZHAOYUN_ATTACK_DELAY);

	if(dir == DIRECTION_RIGHT)
	{
		m_pCurSprite->setAnchorPoint(ccp(81/171.0f, 67.0f/117));
		m_pCurSprite->setFlipX(false);
		m_pCurSprite->setFlipY(false);
	}
	else
	{
		m_pCurSprite->setAnchorPoint(ccp(90/171.0f, 67.0f/117));
		m_pCurSprite->setFlipX(true);
		m_pCurSprite->setFlipY(false);
	}

	m_state = STATE_ATTACK_NORMAL2;
}

void CZhaoYun::AttackCirtical(int dir)
{
	CAnimationHelper::AnimateWithCall(this, callfunc_selector(CZhaoYun::OnAttack), 
		m_pCurSprite, 1, 22, "zhaoyun_attack_critical_%d.png", ZHAOYUN_ATTACK_DELAY);

	if(dir == DIRECTION_RIGHT)
	{
		m_pCurSprite->setAnchorPoint(ccp(33/326.0f, 61 / 293.0f));
		m_pCurSprite->setFlipX(false);
		m_pCurSprite->setFlipY(false);
	}
	else
	{
		m_pCurSprite->setAnchorPoint(ccp(293/326.0f, 61 / 293.0f));
		m_pCurSprite->setFlipX(true);
		m_pCurSprite->setFlipY(false);
	}

	m_state = STATE_ATTACK_CIRTICAL;
}

void CZhaoYun::Skill1(int dir)
{
	CAnimationHelper::AnimateWithCall(this, callfunc_selector(CZhaoYun::OnAttack), 
		m_pCurSprite, 1, 16, "zhaoyun_skill1_%d.png", ZHAOYUN_SKILL1_DELAY);
	if(dir == DIRECTION_RIGHT)
	{
		m_pCurSprite->setAnchorPoint(ccp(198.0f/454.0f, 162 / 315.0f));
		m_pCurSprite->setFlipX(false);
		m_pCurSprite->setFlipY(false);
	}
	else
	{
		m_pCurSprite->setAnchorPoint(ccp(256.0f/454.0f, 162 / 315.0f));
		m_pCurSprite->setFlipX(true);
		m_pCurSprite->setFlipY(false);
	}

	m_state = STATE_ATTACK_SKILL1;
}

void CZhaoYun::Walk(int dir)
{
	if(dir == DIRECTION_RIGHT)
	{
		CAnimationHelper::Animate(m_pCurSprite, 1, 4, "zhaoyun_run_left_%d.png", ZHAOYUN_RUN_DELAY);
		m_pCurSprite->setFlipX(false);
		m_pCurSprite->setFlipY(false);
	}
	else if(dir == DIRECTION_LEFT)
	{
		CAnimationHelper::Animate(m_pCurSprite, 1, 4, "zhaoyun_run_left_%d.png", ZHAOYUN_RUN_DELAY);
		m_pCurSprite->setFlipX(true);
		m_pCurSprite->setFlipY(false);
	}
	else if(dir == DIRECTION_UP)
	{
		CAnimationHelper::Animate(m_pCurSprite, 1, 4, "zhaoyun_run_up_%d.png", ZHAOYUN_RUN_DELAY);
		m_pCurSprite->setFlipX(false);
		m_pCurSprite->setFlipY(false);
	}
	else if(dir == DIRECTION_DOWN)
	{
		CAnimationHelper::Animate(m_pCurSprite, 1, 4, "zhaoyun_run_up_%d.png", ZHAOYUN_RUN_DELAY);
		m_pCurSprite->setFlipX(false);
		m_pCurSprite->setFlipY(true);
	}
	
	m_pCurSprite->setAnchorPoint(ccp(0.5, 0.5));
	m_state = STATE_WALK;
}



void CZhaoYun::Update(cocos2d::ccTime dt)
{
	if(m_bWaitBatter && m_batterTimer > 0)
	{
		m_batterTimer -= dt;

		if(m_batterTimer <=0)
		{
			m_bWaitBatter = false;
			Walk(m_walkDir);

		}
		
	}
}


CLancer::CLancer()
	: m_pCurSprite(NULL)
	, m_pBatchNode(NULL)
	, m_pActRunHor(NULL)
	, m_pActRunUp(NULL)
	, m_pActRunDown(NULL)
	, m_pActPrick(NULL)
	, m_pActSplit(NULL)
	, m_pActAttackedBack(NULL)
	, m_pActDeadFly(NULL)
	, m_pActDeadOrigin(NULL)
{
	
}

void CLancer::InitState(cocos2d::CCNode *pParent)
{
	m_pBatchNode = CCSpriteBatchNode::batchNodeWithFile("chars/lancer.png");
	pParent->addChild(m_pBatchNode);

	m_pActRunHor       = CCRepeatForever::actionWithAction(CAnimationHelper::BuildAnimate(1, 6, "lancer_run_left_%d.png", 0.1));
	m_pActRunDown      = CCRepeatForever::actionWithAction(CAnimationHelper::BuildAnimate(1, 6, "lancer_run_down_%d.png", 0.1f));
	m_pActRunUp        = CCRepeatForever::actionWithAction(CAnimationHelper::BuildAnimate(1, 6, "lancer_run_up_%d.png", 0.1f));
	m_pActPrick        = CCSequence::actions(
		CAnimationHelper::BuildAnimate(1, 3, "lancer_prick_%d.png", 0.2f, 0),
		CCCallFunc::actionWithTarget(this, callfunc_selector(CLancer::SetCanChangeAction)),
		CCDelayTime::actionWithDuration(0.5f),
		CCCallFunc::actionWithTarget(this, callfunc_selector(CLancer::Walk)),
		NULL);

	m_pActSplit        = CCSequence::actions(
		CAnimationHelper::BuildAnimate(1, 4, "lancer_split_%d.png", 0.1f, 0), 
		CCCallFunc::actionWithTarget(this, callfunc_selector(CLancer::SetCanChangeAction)),
		CCDelayTime::actionWithDuration(0.5f),
		CCCallFunc::actionWithTarget(this, callfunc_selector(CLancer::Walk)),
		NULL);

	m_pActAttackedBack = CCSequence::actions(
		CAnimationHelper::BuildAnimate(1, 2, "lancer_attacked_back_%d.png", 0.05f), 
		CCCallFunc::actionWithTarget(this, callfunc_selector(CLancer::SetCanChangeAction)),
		CCDelayTime::actionWithDuration(0.5f),
		CCCallFunc::actionWithTarget(this, callfunc_selector(CLancer::Walk)),
		NULL);

	m_pActDeadFly      = CCSequence::actions(
		CAnimationHelper::BuildAnimate(1, 17, "lancer_dead_fly_%d.png", 0.05f), 
		CCCallFunc::actionWithTarget(this, callfunc_selector(CLancer::SetCanChangeAction)),
		CCFadeOut::actionWithDuration(1.5f),
		NULL);

	m_pActDeadOrigin   = CCSequence::actions(
		CAnimationHelper::BuildAnimate(1, 6, "lancer_dead_origin_%d.png", 0.05f), 
		CCCallFunc::actionWithTarget(this, callfunc_selector(CLancer::SetCanChangeAction)),
		CCFadeOut::actionWithDuration(1.5f),
		NULL);


	m_pActRunHor->retain();
	m_pActRunDown->retain();
	m_pActRunUp->retain();
	m_pActPrick->retain();
	m_pActSplit->retain();
	m_pActAttackedBack->retain();
	m_pActDeadFly->retain();
	m_pActDeadOrigin->retain();
	m_pCurSprite = CCSprite::spriteWithSpriteFrameName("lancer_run_left_1.png");
	m_pBatchNode->addChild(m_pCurSprite);

	
	m_pCurSprite->setPosition(ccp(500, 500));


	m_pCurAction = m_pCurSprite->runAction(m_pActRunDown);

	m_bCanChangeState = true;
}

void CLancer::Move(cocos2d::CCPoint ptAdd)
{
	float xAdd =ptAdd.x;
	float yAdd =ptAdd.y;
	if(xAdd > 0)
	{
		m_attackDir = DIRECTION_RIGHT;
	}
	else
	{
		m_attackDir = DIRECTION_LEFT;
	}

	float moveDir;
	if(abs(xAdd) > abs(yAdd))
	{
		if(xAdd > 0)
		{
			moveDir = DIRECTION_RIGHT;
		}
		else
		{
			moveDir = DIRECTION_LEFT;
		}
	}
	else
	{
		if(yAdd > 0)
		{
			moveDir = DIRECTION_UP;
		}
		else
		{
			moveDir = DIRECTION_DOWN;
		}
	}

	

	m_pCurSprite->setPosition(ccpAdd(m_pCurSprite->getPosition(), ptAdd));

	if(moveDir == m_moveDir)
	{
		return;
	}

	m_moveDir = moveDir;

	Walk();
}

bool CLancer::ChangeVerState()
{
	if(!m_bCanChangeState)
	{
		return false;
	}

	CCActionManager::sharedManager()->removeAction(m_pCurAction);

	if(m_attackDir == DIRECTION_LEFT)
	{
		m_pCurSprite->setFlipX(false);
	}
	else
	{
		m_pCurSprite->setFlipX(true);
	}

	m_pCurSprite->setFlipY(false);

	m_bCanChangeState = false;

	return true;
}

void CLancer::SetCanChangeAction()
{
	m_bCanChangeState = true;
}

void CLancer::Split()
{
	if(!ChangeVerState())
	{
		return;
	}
	m_pCurAction = m_pCurSprite->runAction(m_pActSplit);
}

void CLancer::Prick()
{
	if(!ChangeVerState())
	{
		return;
	}
	m_pCurAction = m_pCurSprite->runAction(m_pActPrick);
}

void CLancer::DeadFly()
{
	if(!ChangeVerState())
	{
		return;
	}

	float dist = LANCER_DEADFLY_DIST;
	if(m_attackDir == DIRECTION_RIGHT)
	{
		dist = - LANCER_DEADFLY_DIST;
	}

	CCPoint ptNew = ccp(m_pCurSprite->getPosition().x + dist, m_pCurSprite->getPosition().y);

	m_pCurAction = m_pCurSprite->runAction(CCSpawn::actions(
		(CCFiniteTimeAction *)m_pActDeadFly, 
		CCSequence::actionOneTwo(CCDelayTime::actionWithDuration(0.3f),
		CCMoveTo::actionWithDuration(0.3f, ptNew)),
		NULL));
}

void CLancer::DeadOrigin()
{
	if(!ChangeVerState())
	{
		return;
	}
	m_pCurAction = m_pCurSprite->runAction(m_pActDeadOrigin);
}

void CLancer::Attacked()
{
	if(!ChangeVerState())
	{
		return;
	}
	m_pCurAction = m_pCurSprite->runAction(m_pActAttackedBack);
}

void CLancer::Walk()
{
	if(!m_bCanChangeState)
	{
		return;
	}
	
	CCActionManager::sharedManager()->removeAction(m_pCurAction);

	if(DIRECTION_RIGHT == m_moveDir)
	{
		m_pCurSprite->setFlipX(true);
		m_pCurSprite->setFlipY(false);
		m_pCurAction = m_pCurSprite->runAction(m_pActRunHor);
	}
	else if(DIRECTION_LEFT == m_moveDir)
	{
		m_pCurSprite->setFlipX(false);
		m_pCurSprite->setFlipY(false);
		m_pCurAction = m_pCurSprite->runAction(m_pActRunHor);
		
	}
	else if(DIRECTION_UP == m_moveDir)
	{
		m_pCurSprite->setFlipX(false);
		m_pCurSprite->setFlipY(false);
		m_pCurAction = m_pCurSprite->runAction(m_pActRunUp);
	}
	else if(DIRECTION_DOWN == m_moveDir)
	{
		m_pCurSprite->setFlipX(false);
		m_pCurSprite->setFlipY(false);
		m_pCurAction = m_pCurSprite->runAction(m_pActRunDown);
	}
}

